package com.yxhl.zoume.common.ui.fragment;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.squareup.leakcanary.RefWatcher;
import com.yxhl.zoume.ZouMeApplication;
import com.yxhl.zoume.common.presenter.BasePresenter;
import com.yxhl.zoume.data.rxbus.RxBus;
import com.yxhl.zoume.di.component.base.AppComponent;
import com.yxhl.zoume.di.component.base.HasComponent;

import javax.inject.Inject;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.subscriptions.CompositeSubscription;

/**
 * Fragment基类
 * 负责绑定控件,内存泄漏检测,设置ToolBar标题,Dagger2依赖注入和管理
 * Created by Xboy on 16/2/24.
 */
public abstract class BaseFragment extends Fragment {

    private static final String TAG = "BaseFragment";

    protected Activity mActivity;

    /**
     * 存放订阅的容器,方便统一解除订阅
     */
    protected CompositeSubscription mSubscription;

    @Inject
    BasePresenter mBasePresenter;
    private Unbinder mUnBinder;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mActivity = (Activity) context;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化注入器
        initializeInjector();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View fragmentView = inflater.inflate(getLayoutResId(), container, false);
        mUnBinder = ButterKnife.bind(this, fragmentView);
        setupToolBar();
        return fragmentView;
    }


    @Override
    public void onResume() {
        super.onResume();
        if (mBasePresenter != null) {
            mBasePresenter.onResume();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (mUnBinder != null) {
            mUnBinder.unbind();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mSubscription != null) {
            mSubscription.unsubscribe();
            mSubscription = null;
        }
        // 内存泄漏监控
        RefWatcher refWatcher = ZouMeApplication.getRefWatcher(getActivity());
        refWatcher.watch(this);
    }

    /**
     * 初始化注入器
     */
    protected abstract void initializeInjector();

    /**
     * 加载布局文件
     *
     * @return
     */
    protected abstract int getLayoutResId();

    /**
     * 配置toolbar, 标题、右侧item
     */
    protected abstract void setupToolBar();

    /**
     * 获取AppComponent
     *
     * @return
     */
    protected AppComponent getAppComponent() {
        if (getActivity() != null) {
            Application application = getActivity().getApplication();
            if (application instanceof ZouMeApplication) {
                ZouMeApplication zouMeApplication = (ZouMeApplication) application;
                return zouMeApplication.getAppComponent();
            }
        }
        return null;
    }

    /**
     * Gets a component for dependency injection by its type.
     * 通过类型获取依赖注入的component
     */
    @SuppressWarnings("unchecked")
    protected <C> C getComponent(Class<C> componentType) {
        return componentType.cast(((HasComponent<C>) getActivity()).getComponent());
    }

    protected CompositeSubscription getSubscription() {
        if (null == mSubscription) {
            mSubscription = new CompositeSubscription();
        }
        return mSubscription;
    }

    protected <T> Subscription toSubscription(Class<T> type, Action1<T> action1) {
        return RxBus.getInstance().toSubscription(type, action1);
    }

    protected <T> Subscription toSubscription(Class<T> type, Action1<T> action1, Action1<Throwable> errorAction1) {
        return RxBus.getInstance().toSubscription(type, action1, errorAction1);
    }

    protected <T> Subscription toSubscription(Class<T> type, Action1<T> action1, Action1<Throwable> errorAction1, Action0 onCompleted) {
        return RxBus.getInstance().toSubscription(type, action1, errorAction1, onCompleted);
    }

    protected String getResString(int resId){
        return mActivity.getResources().getString(resId);
    }
}
